/*
 * @(#)EncodeUtils.java 1.0 2014-5-21下午5:49:20
 *
 * 德邦证券股份有限公司
 * Copyright (c) 2012-2014 Tebon, Inc. All rights reserved.
 */
package com.saturn.config.server.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;


/**
 * <dl>
 *    <dt><b>Title:提供基于编码功能</b></dt>
 *    <dd>
 *    	none
 *    </dd>
 *    <dt><b>Description:</b>提供64位编码，64位编码格式的数据转byte[]方法</dt>
 *    <dd>
 *    	<p>none
 *    </dd>
 * </dl>
 *
 * @author tanks
 * @version 1.0, 2014-5-21
 * @since sirius-commons
 * 
 */
public class EncodeUtils {
	
	public static final String GBK_CHARSET = "GBK";
	public static final String GB2312_CHARSET = "gb2312";
	public static final String UTF8_CHARSET = "utf-8";
	public static final String ISO_CHARSET = "iso-8859-1";

	/**
	 * Hex编码.
	 */
	public static String encodeHex(byte[] input) {
		return Hex.encodeHexString(input);
	}

	/**
	 * Hex解码.
	 */
	public static byte[] decodeHex(String input) {
		try {
			return Hex.decodeHex(input.toCharArray());
		} catch (DecoderException e) {
			throw ExceptionsUtils.unchecked(e);
		}
	}
	
	/** 
	 * 64位编码的字符串
     * @param bytes 
     * @return 
     */  
    public static byte[] decodeBase64(String base64String) {  
        return Base64.decodeBase64(base64String.getBytes());  
    }  
    

	/** 
     * @param bytes 
     * @return 64位编码
     */  
    public static byte[] decodeBase64(final byte[] bytes) {  
        return Base64.decodeBase64(bytes);  
    }  
  
    /** 
     * 二进制数据编码为BASE64字符串 
     * 
     * @param bytes 
     * @return 
     * @throws Exception 
     */  
    public static String encodeBase64(final byte[] bytes) {  
        return new String(Base64.encodeBase64(bytes));  
    }  
    
    /**
     * 对明文进行64位进行编码
     * @param orginTxt
     * @return
     */
    public static String encodeBase64(String orginTxt) {  
        return new String(Base64.encodeBase64(orginTxt.getBytes()));  
    }
    
    /**
     * 返回十六进制字符串
     * @param arr
     * @return
     */
    public static String byteToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i<bytes.length; ++i) {
            sb.append(Integer.toHexString((bytes[i] & 0xFF) | 0x100).substring(1,3));
        }
        return sb.toString();
    }
    
    /**
     * 16进制编码转字符串
     * @param hex     
     * @return
     */
    public static byte[] hexToByte(String hex){
    	 String s2;
         byte[] b = new byte[hex.length() / 2];
         int i;
         for (i = 0; i < hex.length() / 2; i++) {
             s2 = hex.substring(i * 2, i * 2 + 2);
             b[i] = (byte)(Integer.parseInt(s2, 16) & 0xff);
         }
         return b;
    }
    
    /**
	 * 对给定字符进行 URL 编码(GB2312).
	 *
	 * @param src String
	 * @return String
	 */
	public static final String urlEncode(String src) throws Exception{
		if (StringUtils.isBlank(src)) return StringUtils.EMPTY;
		return URLEncoder.encode(src, GB2312_CHARSET);
	}

	/**
	 * 对给定字符进行 URL 编码(charset).
	 *
	 * @param src String
	 * @param charset String
	 * @return String
	 */
	public static final String urlEncode(String src,String charset) throws UnsupportedEncodingException{
		if (StringUtils.isBlank(src)) return StringUtils.EMPTY;
		return URLEncoder.encode(src, charset);
	}
	
	/**
	 * 对给定字符进行 URL 解码(GB2312).
	 * 
	 * @param src String
	 * @return String
	 */
	public static final String urlDecode(String src) throws Exception{
		if (StringUtils.isBlank(src)) return StringUtils.EMPTY;
		return URLDecoder.decode(src, GB2312_CHARSET);
	}

	/**
	 * 对给定字符进行 URL 解码(charset).
	 * @param src
	 * @param charset
	 * @return
	 * @throws Exception
	 */
	public static final String urlDecode(String src,String charset) throws Exception{
		if (StringUtils.isBlank(src)) return StringUtils.EMPTY;
		return URLDecoder.decode(src, charset);
	}


	/**
	 * 将一个字串编码成unicode
	 * @param src
	 * @return
	 */
    public static final String encode2Unicode(String src){
		if (StringUtils.isEmpty(src)) return StringUtils.EMPTY;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < src.length(); i++) {
			sb.append(encode2Unicode(src.charAt(i)));
		}
		return sb.toString();
    }
    
    /**
     * 将一个字符编码成unicode
     * @param c
     * @return
     */
    public static final String encode2Unicode(char c){
    	StringBuffer sb = new StringBuffer();
    	String tmp;
    	if (c > 255) {
			sb.append("\\u");
			//高8位
			tmp = Integer.toHexString(c >>> 8);
			if (tmp.length() == 1) sb.append("0");
			sb.append(tmp);
			//低8位
			tmp = Integer.toHexString(c & 0xff);
			if (tmp.length() == 1) sb.append("0");
			sb.append(tmp);			
		} else {
			sb.append(c);
		}
    	return sb.toString();
    }
    
    /**
     * 将一个字串编码成html所用的某种特殊的unicode
     * @param src
     * @return
     */
    public static final String encode2HtmlUnicode(String src){
		if (StringUtils.isEmpty(src)) return StringUtils.EMPTY;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < src.length(); i++) {	
			sb.append(encode2HtmlUnicode(src.charAt(i)));
		}
		return sb.toString();
    }

    /**
     * 将一个字符编码成html所用的某种特殊的unicode
     * @param c
     * @return
     */
    public static final String encode2HtmlUnicode(char c){
		if (c > 255) {
			return new StringBuffer().append("&#").append(c & 0xffff).append(";").toString();
		} else {
			return String.valueOf(c);
		}
    }
    
    /**
	 * Html 解码.
	 */
	public static String unescapeHtml(String htmlEscaped) {
		return StringEscapeUtils.unescapeHtml4(htmlEscaped);
		
	}

	/**
	 * Xml 转码.
	 */
	public static String escapeXml(String xml) {
		return StringEscapeUtils.escapeXml11(xml);
	}

	/**
	 * Xml 解码.
	 */
	public static String unescapeXml(String xmlEscaped) {
		return StringEscapeUtils.unescapeXml(xmlEscaped);
	}

    
    public static void main(String[] args) throws Exception{
    	String value = "englisahaaaa";
    	String encode = new String(Base64.encodeBase64(value.getBytes()));
    	System.out.println(encode);
    	String decode = new String(EncodeUtils.decodeBase64(encode));
    	System.out.println(decode);
    	encode = EncodeUtils.byteToHex(value.getBytes());
    	System.out.println("Encode:" + encode);
    	System.out.println("Decode:" + new String(EncodeUtils.hexToByte(encode)));
    }
}
